package cn.lili.controller.promotion;

import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.ResultUtil;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.promotion.entity.dos.GreenCommonwealContribution;
import cn.lili.modules.promotion.service.GreenCommonwealContributionService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pojos.OrderModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import jodd.util.StringUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@Api(tags = "用户捐赠接口")
@RequestMapping("/promotion/gc/contribution")
@RequiredArgsConstructor
public class GreenCommonwealContributionController {

    private final RedissonClient redissonClient;

    private final GreenCommonwealContributionService greenCommonwealContributionService;

    @RequestMapping("/add")
    @ApiModelProperty("用户捐赠接口")
    public ResultMessage<Object> add (String money) {
        if (StringUtil.isEmpty(money)) {
            throw new ServiceException(ResultCode.PARAMS_ERROR);
        }
        RLock lock = redissonClient.getLock("contribution_" + UserContext.getCurrentId());
        try {
            lock.lock();
            Map<String, Object> result = greenCommonwealContributionService.add(Objects.requireNonNull(UserContext.getCurrentUser()).getOpenId(), money);
            return ResultUtil.data(result);
        }catch (Exception e) {
            log.info("捐赠失败:{}", e.getMessage());
            throw new ServiceException("捐赠失败");
        }finally {
            if(lock.isLocked()) {
                lock.unlock();
            }
        }
    }

    @RequestMapping("/callback")
    @ApiModelProperty("用户捐赠接口回调")
    public String callback (OrderModel orderMessage) throws InterruptedException {
        log.info("---------收到回调-------");
        RLock lock = redissonClient.getLock("contribution_callback_" + orderMessage.getOrderno());
        boolean b = lock.tryLock(2000, 3000, TimeUnit.MILLISECONDS);
        try {
            if (b) {
                String msg = greenCommonwealContributionService.callback(orderMessage);
                if (StringUtil.isEmpty(msg)) {
                    return "SUCCESS";
                }
                log.info("Faild====={}", msg);
                return "FAILD";
            }
        }catch (Exception e) {
            log.error("回调失败:{}", e);
        }finally {
            if(lock.isLocked()) {
                lock.unlock();
            }
        }
        return "FAILD";
    }

    @ApiModelProperty("分页查询捐赠记录")
    @GetMapping
    public ResultMessage<Object> getPage (PageVO pageVO) {
        return ResultUtil.data(greenCommonwealContributionService.getPage(pageVO));
    }

    @GetMapping("getByPage")
    @ApiModelProperty("分页查询捐赠记录")
    public ResultMessage<Page<GreenCommonwealContribution>> getByPage(GreenCommonwealContribution contribution, PageVO pageVO) {
        return ResultUtil.data(greenCommonwealContributionService.getPageByParams(contribution, pageVO));
    }

    @GetMapping("getUserBalance")
    @ApiModelProperty("获取用户绿色积分余额")
    public ResultMessage<Object> getUserBalance () {
        return ResultUtil.data(greenCommonwealContributionService.getUserBalance());
    }

    @GetMapping("getContributionPage")
    @ApiModelProperty("分页查询捐赠记录")
    public ResultMessage<Page<GreenCommonwealContribution>> getContributionPage(GreenCommonwealContribution contribution, PageVO pageVO) {
        return ResultUtil.data(greenCommonwealContributionService.getContributionPage(contribution, pageVO));
    }
}
